package com.tian.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2023年05月14日 22:19
 * 博客地址：<a href="http://woaijava.cc/">博客地址</a>
 *
 * RabbitMQ配置
 */

@Configuration
public class RabbitConfig {
    @Value("${rabbitmq.order.pay.overtime.queue.name}")
    private String orderPayOvertimeQueueName;
    @Value("${rabbitmq.order.pay.overtime.exchange.name}")
    private String orderPayOvertimeExchangeName;
    @Value("${rabbitmq.order.pay.overtime.binding.key}")
    private String orderPayOvertimeBindingKey;

    @Value("${rabbitmq.order.pay.overtime.dead.queue.name}")
    private String orderPayOvertimeDeadQueueName;
    @Value("${rabbitmq.order.pay.overtime.dead.exchange.name}")
    private String orderPayOvertimeDeadExchangeName;
    @Value("${rabbitmq.order.pay.overtime.dead.binding.key}")
    private String orderPayOvertimeDeadBindingKey;
    @Value("${order.pay.overtime}")
    private Long orderPayOvertime;

    @Value("${rabbitmq.point.init.message.queue.name}")
    private String pointInitQueueName;
    @Value("${rabbitmq.point.init.message.exchange.name")
    private String pointInitExchangeName;
    @Value("${rabbitmq.point.init.message.binding.key}")
    private String pointInitBindingKey;

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));
        return rabbitTemplate;
    }

    @Bean(name = "rabbitListener")
    public SimpleRabbitListenerContainerFactory listenerContainer(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));
        return factory;
    }

    /**
     * 订单超时死信队列
     */
    @Bean("orderPayOvertimeDeadQueue")
    public Queue orderPayOvertimeDeadQueue() {
        return new Queue(orderPayOvertimeDeadQueueName);
    }

    /**
     * 订单超时死信交换机
     */
    @Bean("orderPayOvertimeDeadExchange")
    public Exchange orderPayOvertimeDeadExchange() {
        return new DirectExchange(orderPayOvertimeDeadExchangeName);
    }

    /**
     * 绑定 订单超时死信队列->订单超时死信交换机
     */
    @Bean
    public Binding orderPayOvertimeDeadBinding(@Qualifier("orderPayOvertimeDeadQueue") Queue deadQueue, @Qualifier("orderPayOvertimeDeadExchange") Exchange deadExchange) {
        return BindingBuilder.bind(deadQueue).to(deadExchange).with(orderPayOvertimeDeadBindingKey).noargs();
    }

    /**
     * 订单超时队列
     */
    @Bean
    public Queue orderPayOvertimeQueue() {
        HashMap<String, Object> hashMap = new HashMap<>(3);
        //定义消息存活时间15秒
        hashMap.put("x-message-ttl", orderPayOvertime * 1000);
        //设置此队列产生的死信会投递给哪个交换机
        hashMap.put("x-dead-letter-exchange", orderPayOvertimeDeadExchangeName);
        //设置死信投递时使用的路由键
        hashMap.put("x-dead-letter-routing-key", orderPayOvertimeDeadBindingKey);
        return QueueBuilder.durable(orderPayOvertimeQueueName).withArguments(hashMap).build();
    }

    /**
     * 订单超时交换机
     */
    @Bean("orderPayOvertimeExchange")
    public Exchange orderPayOvertimeExchange() {
        return new DirectExchange(orderPayOvertimeExchangeName);
    }

    /**
     * 绑定 订单超时队列->订单超时交换机
     */
    @Bean("orderPayOvertimeBinding")
    public Binding orderPayOvertimeBinding(@Qualifier("orderPayOvertimeQueue") Queue deadQueue, @Qualifier("orderPayOvertimeExchange") Exchange deadExchange) {
        return BindingBuilder.bind(deadQueue).to(deadExchange).with(orderPayOvertimeBindingKey).noargs();
    }


    @Bean("pointInitQueue")
    public Queue pointInitQueue() {
        return new Queue(pointInitQueueName);
    }
    @Bean("pointInitExchange")
    public Exchange pointInitExchange() {
        return new DirectExchange(pointInitExchangeName);
    }
    @Bean
    public Binding pointInitBinding(@Qualifier("pointInitQueue") Queue queue, @Qualifier("pointInitExchange") Exchange pointInitExchange) {
        return BindingBuilder.bind(queue).to(pointInitExchange).with(pointInitBindingKey).noargs();
    }


}


